From d12d40363fd6e03e87dd1531811fcb3c295cfab2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Fri, 1 Sep 2017 20:03:13 +0200 Subject: [PATCH] babl: make trcs capable of iterating buffers --- babl/babl-fish-path.c | 203 ++++++++++++++---------------------------- babl/babl-trc.c | 119 +++++++++++++++++++++++++ babl/babl-trc.h | 31 +++++++ 3 files changed, 218 insertions(+), 135 deletions(-) diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c index 9236119..176f02f 100644 --- a/babl/babl-fish-path.c +++ b/babl/babl-fish-path.c @@ -431,56 +431,35 @@ universal_nonlinear_rgb_converter (const Babl *conversion,unsigned char *src_cha const Babl *source_space = babl_conversion_get_source_space (conversion); const Babl *destination_space = babl_conversion_get_destination_space (conversion); - void *to_trc_red; - void *to_trc_green; - void *to_trc_blue; - float (*to_linear_red) (void *trc, float value); - float (*to_linear_green) (void *trc, float value); - float (*to_linear_blue) (void *trc, float value); - void *from_trc_red; - void *from_trc_green; - void *from_trc_blue; - float (*from_linear_red) (void *trc, float value); - float (*from_linear_green) (void *trc, float value); - float (*from_linear_blue) (void *trc, float value); - float * matrixf = conversion->conversion.data; - int i; float *rgba_in = (void*)src_char; float *rgba_out = (void*)dst_char; - to_linear_red = (void*)source_space->space.trc[0]->trc.fun_to_linear; - to_trc_red = (void*)source_space->space.trc[0]; - from_linear_red = (void*)destination_space->space.trc[0]->trc.fun_from_linear; - from_trc_red = (void*)destination_space->space.trc[0]; - - to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear; - to_trc_green = (void*)source_space->space.trc[1]; - from_linear_green= (void*)destination_space->space.trc[1]->trc.fun_from_linear; - from_trc_green = (void*)destination_space->space.trc[1]; - - to_linear_blue = (void*)source_space->space.trc[2]->trc.fun_to_linear; - to_trc_blue = (void*)source_space->space.trc[2]; - from_linear_blue= (void*)destination_space->space.trc[2]->trc.fun_from_linear; - from_trc_blue = (void*)destination_space->space.trc[2]; - + { + int i; for (i = 0; i < samples; i++) { - rgba_out[i*4] =to_linear_red(to_trc_red, rgba_in[i*4]); - rgba_out[i*4+1]=to_linear_green(to_trc_green, rgba_in[i*4+1]); - rgba_out[i*4+2]=to_linear_blue(to_trc_blue, rgba_in[i*4+1]); - rgba_out[i*4+3]=rgba_in[3]; + rgba_out[i*4+3] = rgba_in[i*4+3]; + } + } + { + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)source_space->space.trc[c]; + babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples); + } } babl_matrix_mul_vectorff_buf4 (matrixf, rgba_out, rgba_out, samples); - for (i = 0; i < samples; i++) { - rgba_out[0] = from_linear_red(from_trc_red, rgba_out[0]); - rgba_out[1] = from_linear_green(from_trc_green, rgba_out[1]); - rgba_out[2] = from_linear_blue(from_trc_blue, rgba_out[2]); - rgba_in += 4; - rgba_out += 4; + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)destination_space->space.trc[c]; + babl_trc_from_linear_buf(trc, rgba_out + c, rgba_out + c, 4, 4, samples); + } } return samples; @@ -490,33 +469,24 @@ static inline long universal_nonlinear_rgb_linear_converter (const Babl *conversion,unsigned char *src_char, unsigned char *dst_char, long samples) { const Babl *source_space = babl_conversion_get_source_space (conversion); - - void *to_trc_red; - void *to_trc_green; - void *to_trc_blue; - float (*to_linear_red) (void *trc, float value); - float (*to_linear_green) (void *trc, float value); - float (*to_linear_blue) (void *trc, float value); - float * matrixf = conversion->conversion.data; - int i; float *rgba_in = (void*)src_char; float *rgba_out = (void*)dst_char; - to_linear_red = (void*)source_space->space.trc[0]->trc.fun_to_linear; - to_trc_red = (void*)source_space->space.trc[0]; - to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear; - to_trc_green = (void*)source_space->space.trc[1]; - to_linear_blue = (void*)source_space->space.trc[2]->trc.fun_to_linear; - to_trc_blue = (void*)source_space->space.trc[2]; - + { + int i; for (i = 0; i < samples; i++) { - rgba_out[i*4] = to_linear_red (to_trc_red, rgba_in[0]); - rgba_out[i*4+1] = to_linear_green(to_trc_green, rgba_in[1]); - rgba_out[i*4+2] = to_linear_blue (to_trc_blue, rgba_in[2]); - rgba_out[i*4+3] = rgba_in[3]; - rgba_in += 4; + rgba_out[i*4+3] = rgba_in[i*4+3]; + } + } + { + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)source_space->space.trc[c]; + babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples); + } } babl_matrix_mul_vectorff_buf4 (matrixf, rgba_out, rgba_out, samples); @@ -626,59 +596,31 @@ universal_nonlinear_rgb_converter_sse2 (const Babl *conversion,unsigned char *sr { const Babl *source_space = babl_conversion_get_source_space (conversion); const Babl *destination_space = babl_conversion_get_destination_space (conversion); - - void *to_trc_red; - void *to_trc_green; - void *to_trc_blue; - float (*to_linear_red) (void *trc, float value); - float (*to_linear_green) (void *trc, float value); - float (*to_linear_blue) (void *trc, float value); - void *from_trc_red; - void *from_trc_green; - void *from_trc_blue; - float (*from_linear_red) (void *trc, float value); - float (*from_linear_green) (void *trc, float value); - float (*from_linear_blue) (void *trc, float value); - float * matrixf = conversion->conversion.data; int i; float *rgba_in = (void*)src_char; float *rgba_out = (void*)dst_char; - - to_linear_red = (void*)source_space->space.trc[0]->trc.fun_to_linear; - to_trc_red = (void*)source_space->space.trc[0]; - from_linear_red = (void*)destination_space->space.trc[0]->trc.fun_from_linear; - from_trc_red = (void*)destination_space->space.trc[0]; - - to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear; - to_trc_green = (void*)source_space->space.trc[1]; - from_linear_green= (void*)destination_space->space.trc[1]->trc.fun_from_linear; - from_trc_green = (void*)destination_space->space.trc[1]; - - to_linear_blue = (void*)source_space->space.trc[2]->trc.fun_to_linear; - to_trc_blue = (void*)source_space->space.trc[2]; - from_linear_blue= (void*)destination_space->space.trc[2]->trc.fun_from_linear; - from_trc_blue = (void*)destination_space->space.trc[2]; - + { + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)source_space->space.trc[c]; + babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples); + } + } for (i = 0; i < samples; i++) { - rgba_out[i*4] =to_linear_red(to_trc_red, rgba_in[i*4]); - rgba_out[i*4+1]=to_linear_green(to_trc_green, rgba_in[i*4+1]); - rgba_out[i*4+2]=to_linear_blue(to_trc_blue, rgba_in[i*4+1]); rgba_out[i*4+3]=rgba_in[3]; } - babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgba_out, rgba_out, samples); - - for (i = 0; i < samples; i++) { - rgba_out[0] = from_linear_red(from_trc_red, rgba_out[0]); - rgba_out[1] = from_linear_green(from_trc_green, rgba_out[1]); - rgba_out[2] = from_linear_blue(from_trc_blue, rgba_out[2]); - rgba_in += 4; - rgba_out += 4; + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)destination_space->space.trc[c]; + babl_trc_from_linear_buf(trc, rgba_out + c, rgba_out + c, 4, 4, samples); + } } - return samples; } @@ -713,23 +655,23 @@ universal_nonlinear_rgba_u8_converter_sse2 (const Babl *conversion,unsigned char rgb[i*4+0]=in_trc_lut[rgba_in_u8[i*4+0]]; rgb[i*4+1]=in_trc_lut[rgba_in_u8[i*4+1]]; rgb[i*4+2]=in_trc_lut[rgba_in_u8[i*4+2]]; + rgba_out_u8[i*4+3] = rgba_in_u8[i*4+3]; } babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgb, rgb, samples); { - const Babl *from_trc_red = (void*)destination_space->space.trc[0]; - const Babl *from_trc_green = (void*)destination_space->space.trc[1]; - const Babl *from_trc_blue = (void*)destination_space->space.trc[2]; - for (i = 0; i < samples; i++) - { - rgba_out_u8[0] = babl_trc_from_linear (from_trc_red, rgb[i*4+0]) * 255.5f; - rgba_out_u8[1] = babl_trc_from_linear (from_trc_green, rgb[i*4+1]) * 255.5f; - rgba_out_u8[2] = babl_trc_from_linear (from_trc_blue, rgb[i*4+2]) * 255.5f; - rgba_out_u8[3] = rgba_in_u8[3]; - rgba_in_u8 += 4; - rgba_out_u8 += 4; - } + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)destination_space->space.trc[0]; + babl_trc_from_linear_buf(trc, rgb + c, rgb + c, 4, 4, samples); + } + + /* XXX: this is a prime candidate for sseification */ + for (i = 0; i < samples; i++) + for (c = 0; c < 3; c ++) + rgba_out_u8[i*4+c] = rgb[i*4+c] * 255.5f; } return samples; @@ -739,33 +681,24 @@ static inline long universal_nonlinear_rgb_linear_converter_sse2 (const Babl *conversion,unsigned char *src_char, unsigned char *dst_char, long samples) { const Babl *source_space = babl_conversion_get_source_space (conversion); - - void *to_trc_red; - void *to_trc_green; - void *to_trc_blue; - float (*to_linear_red) (void *trc, float value); - float (*to_linear_green) (void *trc, float value); - float (*to_linear_blue) (void *trc, float value); - float * matrixf = conversion->conversion.data; - int i; float *rgba_in = (void*)src_char; float *rgba_out = (void*)dst_char; - to_linear_red = (void*)source_space->space.trc[0]->trc.fun_to_linear; - to_trc_red = (void*)source_space->space.trc[0]; - to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear; - to_trc_green = (void*)source_space->space.trc[1]; - to_linear_blue = (void*)source_space->space.trc[2]->trc.fun_to_linear; - to_trc_blue = (void*)source_space->space.trc[2]; - + { + int i; for (i = 0; i < samples; i++) { - rgba_out[i*4] = to_linear_red (to_trc_red, rgba_in[0]); - rgba_out[i*4+1] = to_linear_green(to_trc_green, rgba_in[1]); - rgba_out[i*4+2] = to_linear_blue (to_trc_blue, rgba_in[2]); - rgba_out[i*4+3] = rgba_in[3]; - rgba_in += 4; + rgba_out[i*4+3] = rgba_in[i*4+3]; + } + } + { + int c; + for (c = 0; c < 3; c ++) + { + const Babl *trc = (void*)source_space->space.trc[c]; + babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples); + } } babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgba_out, rgba_out, samples); diff --git a/babl/babl-trc.c b/babl/babl-trc.c index 9275cb6..e22a71a 100644 --- a/babl/babl-trc.c +++ b/babl/babl-trc.c @@ -349,6 +349,26 @@ static inline float _babl_trc_gamma_to_linear (const Babl *trc_, float value) return babl_powf (value, trc->gamma); } + +static inline void _babl_trc_gamma_to_linear_buf (const Babl *trc_, const float *in, float *out, int in_gap, int out_gap, int count) +{ + BablTRC *trc = (void*)trc_; + float gamma = trc->gamma; + int i; + for (i = 0; i < count; i ++) + out[out_gap * i] = babl_powf (in[in_gap *i], gamma); +} + + +static inline void _babl_trc_gamma_from_linear_buf (const Babl *trc_, const float *in, float *out, int in_gap, int out_gap, int count) +{ + BablTRC *trc = (void*)trc_; + float gamma = trc->rgamma; + int i; + for (i = 0; i < count; i ++) + out[out_gap * i] = babl_powf (in[in_gap *i], gamma); +} + static inline float _babl_trc_gamma_from_linear (const Babl *trc_, float value) { BablTRC *trc = (void*)trc_; @@ -478,6 +498,92 @@ static inline float _babl_trc_srgb_from_linear (const Babl *trc_, float value) return babl_linear_to_gamma_2_2f (value); } +static inline void _babl_trc_srgb_to_linear_buf (const Babl *trc_, const float *in, float *out, int in_gap, int out_gap, int count) +{ + int i; + for (i = 0; i < count; i ++) + out[out_gap * i] = babl_gamma_2_2_to_linearf (in[in_gap * i]); +} + +static inline void _babl_trc_srgb_from_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[out_gap * i] = babl_linear_to_gamma_2_2f (in[in_gap * i]); +} + +static inline void _babl_trc_to_linear_buf_generic (const Babl *trc_, const float *in, float *out, int in_gap, int out_gap, int count) +{ + int i; + BablTRC *trc = (void*)trc_; + for (i = 0; i < count; i ++) + out[out_gap * i] = trc->fun_to_linear (trc_, in[in_gap * i]); +} + +static inline void _babl_trc_from_linear_buf_generic (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + BablTRC *trc = (void*)trc_; + for (i = 0; i < count; i ++) + out[out_gap * i] = trc->fun_from_linear (trc_, in[in_gap * i]); +} + +static inline void _babl_trc_gamma_1_8_from_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[i * out_gap] = _babl_trc_gamma_1_8_from_linear (trc_, in[i * in_gap]); +} + +static inline void _babl_trc_gamma_2_2_from_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[i * out_gap] = _babl_trc_gamma_2_2_from_linear (trc_, in[i * in_gap]); +} + +static inline void _babl_trc_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[i * out_gap] = in[i * in_gap]; +} + +static inline void _babl_trc_gamma_1_8_to_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[i * out_gap] = _babl_trc_gamma_1_8_to_linear (trc_, in[i * in_gap]); +} + +static inline void _babl_trc_gamma_2_2_to_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + int i; + for (i = 0; i < count; i ++) + out[i * out_gap] = _babl_trc_gamma_2_2_to_linear (trc_, in[i * in_gap]); +} + const Babl * babl_trc (const char *name) @@ -557,27 +663,40 @@ babl_trc_new (const char *name, babl_trc_to_linear (BABL(&trc_db[i]), trc_db[i].lut[(int) ( j/(n_lut-1.0) * (n_lut-1))]); } + trc_db[i].fun_to_linear_buf = _babl_trc_to_linear_buf_generic; + trc_db[i].fun_from_linear_buf = _babl_trc_from_linear_buf_generic; + switch (trc_db[i].type) { case BABL_TRC_LINEAR: trc_db[i].fun_to_linear = _babl_trc_linear; trc_db[i].fun_from_linear = _babl_trc_linear; + trc_db[i].fun_from_linear_buf = _babl_trc_linear_buf; + trc_db[i].fun_to_linear_buf = _babl_trc_linear_buf; break; case BABL_TRC_GAMMA: trc_db[i].fun_to_linear = _babl_trc_gamma_to_linear; trc_db[i].fun_from_linear = _babl_trc_gamma_from_linear; + trc_db[i].fun_to_linear_buf = _babl_trc_gamma_to_linear_buf; + trc_db[i].fun_from_linear_buf = _babl_trc_gamma_from_linear_buf; break; case BABL_TRC_GAMMA_2_2: trc_db[i].fun_to_linear = _babl_trc_gamma_2_2_to_linear; trc_db[i].fun_from_linear = _babl_trc_gamma_2_2_from_linear; + trc_db[i].fun_from_linear_buf = _babl_trc_gamma_2_2_from_linear_buf; + trc_db[i].fun_to_linear_buf = _babl_trc_gamma_2_2_to_linear_buf; break; case BABL_TRC_GAMMA_1_8: trc_db[i].fun_to_linear = _babl_trc_gamma_1_8_to_linear; trc_db[i].fun_from_linear = _babl_trc_gamma_1_8_from_linear; + trc_db[i].fun_from_linear_buf = _babl_trc_gamma_1_8_from_linear_buf; + trc_db[i].fun_to_linear_buf = _babl_trc_gamma_1_8_to_linear_buf; break; case BABL_TRC_SRGB: trc_db[i].fun_to_linear = _babl_trc_srgb_to_linear; trc_db[i].fun_from_linear = _babl_trc_srgb_from_linear; + trc_db[i].fun_from_linear_buf = _babl_trc_srgb_from_linear_buf; + trc_db[i].fun_to_linear_buf = _babl_trc_srgb_to_linear_buf; break; case BABL_TRC_LUT: trc_db[i].fun_to_linear = babl_trc_lut_to_linear; diff --git a/babl/babl-trc.h b/babl/babl-trc.h index dc1abf9..4dafd04 100644 --- a/babl/babl-trc.h +++ b/babl/babl-trc.h @@ -42,11 +42,42 @@ typedef struct float rgamma; float (*fun_to_linear)(const Babl *trc, float val); float (*fun_from_linear)(const Babl *trc, float val); + + void (*fun_to_linear_buf)(const Babl *trc, + const float *in, + float *out, + int in_gap, + int out_gap, + int count); + void (*fun_from_linear_buf)(const Babl *trc, + const float *in, + float *out, + int in_gap, + int out_gap, + int count); float *lut; float *inv_lut; char name[128]; } BablTRC; +static inline void babl_trc_from_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + BablTRC *trc = (void*)trc_; + trc->fun_from_linear_buf (trc_, in, out, in_gap, out_gap, count); +} + +static inline void babl_trc_to_linear_buf (const Babl *trc_, + const float *in, float *out, + int in_gap, int out_gap, + int count) +{ + BablTRC *trc = (void*)trc_; + trc->fun_to_linear_buf (trc_, in, out, in_gap, out_gap, count); +} + static inline float babl_trc_from_linear (const Babl *trc_, float value) { BablTRC *trc = (void*)trc_; -- 2.30.2